/* 
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
define(function() {
    return function() {
        /**
         * _url: url of web service
         * successCallback: a function accepts the loaded model
         * failCallback: a function accepts an xhr object
         */
        function load(_url, successCallback, failCallback, _type, _parameters) {
            if (!_type) {
                _type = "GET";
            }
            if (!_parameters) {
                _parameters = {};
            }
            if (_type == "GET") {
                $.ajax({
                    url: this.createURL(_url, _parameters),
                    type: _type,
                    success: function(data) {
                        if (successCallback) {
                            successCallback(eval("(" + data + ")"));
                        }
                    },
                    error: function(xhr) {
                        if (failCallback) {
                            failCallback(xhr);
                        }
                    }
                });
            }
            else {
                $.ajax({
                    url: _url,
                    type: _type,
                    data: _parameters,
                    success: function(data) {
                        if (successCallback) {
                            successCallback(eval("(" + data + ")"));
                        }
                    },
                    error: function(xhr) {
                        if (failCallback) {
                            failCallback(xhr);
                        }
                    }
                });
            }
        };
        /**
         * _url: url of web service
         * successCallback: a function accepts the returned data
         * failCallback: a function accepts an xhr object
         */
        function save(_url, packet, successCallback, failCallback) {
            $.ajax({
                type: "POST",
                url: _url,
                data: {
                    "data": packet
                },
                success: function(data) {
                    if (successCallback) {
                        successCallback(data);
                    }
                },
                error: function(xhr) {
                    if (failCallback) {
                        failCallback(xhr);
                    }
                }
            });
        };
        function create(_header, _skipData) {
            return {
                header: _header,
                data: (_skipData) ? [] : [{}]
            };
        };
        /**
         * prepare a normal save packet
         * in json format, this usually
         * represents a transaction
         */
        function createNormalSavePacket(model) {
            var packet = {
                "header": {"type": "saveOrUpdate", "paradigm": "normal"},
                "data": model
            };
            return packet;
        };
        function createMasterDetailSavePacket(masterModel, detailModel) {
            var packet = {
                "header": {"type": "saveOrUpdate", "paradigm": "masterDetail"},
                "master": masterModel,
                "detail": detailModel
            };
            return packet;
        };
        /**
         * always return array of objects no matter the given
         * parameter is model, object, or array of objects
         */
        function getArrayOfObjects(modelOrObjectOrArray) {
            var collectedObjects = Array();
            if (modelOrObjectOrArray["data"] && modelOrObjectOrArray["data"].constructor == Array) {
                //obj is a model
                for (var j in modelOrObjectOrArray["data"]) {
                    collectedObjects[collectedObjects.length] = modelOrObjectOrArray["data"][j];
                }
            }
            else if (modelOrObjectOrArray.constructor == Array) {
                //obj is an array of objects
                for (var j in modelOrObjectOrArray) {
                    collectedObjects[collectedObjects.length] = modelOrObjectOrArray[j];
                }
            }
            else {
                //obj itself is an object
                collectedObjects[collectedObjects.length] = modelOrObjectOrArray;
            }
            return collectedObjects;
        };
        /**
         * construct a valid url
         * @param parameters parameters to be used in the url
         */
        function createURL(baseURL, parameters) {
            var url = baseURL;
            var postfix = "";
            if (postfix.length == 0) {
                postfix += "?";
            }
            for (var key in parameters) {
                if (postfix != "?") {
                    postfix += "&";
                }
                postfix += key + "=" + encodeURIComponent(parameters[key]);
            }
            if (postfix != "?") {
                return url + postfix;
            }
            else {
                return url;
            }
        }
        this.load=load;
        this.save=save;
        this.create=create;
        this.createNormalSavePacket=createNormalSavePacket;
        this.createMasterDetailSavePacket=createMasterDetailSavePacket;
        this.getArrayOfObjects=getArrayOfObjects;
        this.createURL=createURL;
        
        return this;
    }
});

